package com.violet.common.exception;

import com.violet.common.constant.business.CodeEnum;
import com.violet.common.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * 类说明: 全局异常处理器
 *
 * @author wqf
 * @date 2022/1/14 9:48
 */
@Slf4j
@ResponseBody
public class DefaultExceptionAdvice {


    /**
     * 参数错误异常捕获
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({IllegalArgumentException.class})
    public Result<String> badRequestException(IllegalArgumentException e) {
        return Result.failure(CodeEnum.PARAMETER_PARSE_ERROR.getCode(), "参数解析异常");
    }

    //其他异常捕获
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = Exception.class)
    public Result<String> exceptionHandler(Exception e) {
        return Result.failure(CodeEnum.SYSTEM_EXECUTION_ERROR.getCode(), "系统异常，请联系后端管理员");
    }

    //业务异常捕获
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = BusinessException.class)
    public Result<String> businessExceptionHandler(BusinessException e) {
        return Result.failure(CodeEnum.SYSTEM_EXECUTION_ERROR.getCode(), e.getMessage());
    }

    /**
     * 方法描述: 参数校验异常捕获
     *
     * @param e 异常信息
     * @return pers.darcy.flower.utils.util.response.Result<pers.darcy.flower.utils.util.response.WebResponseBody < java.lang.String>>
     * @author wqf
     * @date 2022/5/27 9:55
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        // 从异常对象中拿到ObjectError对象
        ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
        // 然后提取错误提示信息进行返回
        String defaultMessage = objectError.getDefaultMessage();
        return Result.failure(CodeEnum.CLIENT_ERROR.getCode(), defaultMessage);
    }

    /**
     * 方法描述: 处理@Vaild参数校验异常
     *
     * @return pers.darcy.flower.utils.util.response.Result<pers.darcy.flower.utils.util.response.WebResponseBody < java.lang.String>>
     * @author wqf
     * @date 2022/5/27 9:55
     */
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(IdentityInfoExpiredException.class)
    public Result<String> identityInfoExpiredException() {
        return Result.failure(CodeEnum.LOGIN_INFORMATION_INVALID.getCode(), "登录信息失效,请重新登陆");
    }

    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(AccessDeniedException.class)
    public Result<String> accessDeniedException() {
        return Result.failure(CodeEnum.LOGIN_INFORMATION_INVALID.getCode(), "无权访问");
    }

    /**
     * 方法描述: 处理@Vaild参数校验异常
     *
     * @return pers.darcy.flower.utils.util.response.Result<pers.darcy.flower.utils.util.response.WebResponseBody < java.lang.String>>
     * @author wqf
     * @date 2022/5/27 9:55
     */
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ExceptionHandler(NoPermissionException.class)
    public Result<String> noPermissionException() {
        return Result.failure(CodeEnum.FORBIDDEN.getCode(), "暂无权限，请联系后端管理员");
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({BadCredentialsException.class, UsernameNotFoundException.class})
    public Result<String> badCredentialsException() {
        return Result.failure(CodeEnum.ACCOUNT_PASSWORD_ERROR.getCode(), "账号或密码错误");
    }

}